package com.bsh.serviceImpl;

import java.math.BigDecimal;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.bsh.mybatis.dataView.UserAccountInfo;
import com.bsh.mybatis.model.Account;
import com.bsh.mybatis.model.AccountNotice;
import com.bsh.mybatis.model.CloudUserGoods;
import com.bsh.mybatis.model.User;
import com.bsh.repository.DaoAccount;
import com.bsh.repository.DaoAccountLog;
import com.bsh.repository.DaoAccountNotice;
import com.bsh.repository.DaoCloudUserGoods;
import com.bsh.repository.DaoUser;
import com.bsh.service.CloudUserGoodsService;
import com.bsh.service.RecommendService;
import com.bsh.utils.PrimaryGenerater;
import com.bsh.utils.system.AccountLock;

@Transactional
@Service
public class CloudUserGoodsServiceImpl implements CloudUserGoodsService {
	private static Logger log = LoggerFactory.getLogger(CloudUserGoodsServiceImpl.class);

	@Autowired
	DaoCloudUserGoods daoCloudUserGoods;
	@Autowired
	DaoAccountLog daoAccLog;
	@Autowired
	DaoAccount daoAcc;
	@Autowired
	DaoAccountNotice daoNotice;
	@Autowired
	DaoUser daoUser;
	@Autowired
	RecommendService recommendSer;

	/**
	 * 添加用户兑换信息
	 */
	@Override
	public Integer addCloudUserGoods(CloudUserGoods cloudUserGoods) {
		return daoCloudUserGoods.insert(cloudUserGoods);
	}

	/**
	 * 扣减商币
	 */
	@Override
	public Integer DeductCloudMoney(int accountId, int userid, String sn, String ip, BigDecimal cloudMoney) {

		// 账户变动前记录日志
		daoAccLog.addLog(accountId, sn, ip);
		// 扣减商币
		cloudMoney = BigDecimal.ZERO.subtract(cloudMoney);
		daoAcc.addCloudMoney(accountId, userid, cloudMoney);
		UserAccountInfo endAccInfo = getUserAccountInfo(userid);
		// 写资金日志明细
		AccountNotice notice = new AccountNotice();
		notice.setAccountId(accountId);
		notice.setUserid(userid);
		notice.setCloudMoney(cloudMoney);
		notice.setTradeType(18); // 商币兑换
		notice.setSn(sn);// 流水号
		notice.setOuterTime(new Date());
		notice.setOperator(userid);// 操作人
		notice.setTitle(String.format("商币兑换: %s ,操作人:%s", cloudMoney, endAccInfo.getName()));
		// notice.setMemo(accChangeInfo.getMemo());
		notice.setPaymentId(3);// 系统自动操作
		notice.setIp(ip);
		notice.setIsPaid((byte) 1);// 已付款
		notice.setMoneyType((short) 0);// 商币
		notice.setCreateTime(new Date());
		notice.setCloudMoneyDown(endAccInfo.getCloudMoney()); // 结存商币余额
		return daoNotice.insert(notice);
	}

	public UserAccountInfo getUserAccountInfo(int userid) {
		UserAccountInfo userAcc = null;
		User user = daoUser.selectByPrimaryKey(userid);
		if (user == null)
			return userAcc;

		userAcc = new UserAccountInfo();
		userAcc.setName(user.getName());
		userAcc.setEnabled(user.getIsEffect());
		userAcc.setUserid(user.getId());

		Account acc = daoAcc.getUserAccount(userid);
		BigDecimal money = null, cloudMoney = null, cloudshares = null;
		if (acc != null) {
			money = acc.getMoney() == null ? BigDecimal.ZERO : acc.getMoney();
			cloudMoney = acc.getCloudMoney() == null ? BigDecimal.ZERO : acc.getCloudMoney();
			userAcc.setAccountId(acc.getId());
		}
		if (acc == null) {
			money = cloudMoney = cloudshares = BigDecimal.ZERO;
		}
		userAcc.setMoney(money);
		userAcc.setCloudMoney(cloudMoney);
		userAcc.setCloudShares(cloudshares);
		return userAcc;
	}

	/**
	 * 赠送商币
	 */
	@Override
	public Integer sendCloudMoney(int accountId, int userid, int toAccountId, int toUserid, String sn, String ip,
			BigDecimal cloudMoney, String memo) {
		Integer res=-1;
		// 添加账务锁
		boolean isLock = AccountLock.getLock(accountId, userid);
		if (!isLock) {
			res = -11;
			return res;
		}

		// 账户变动前记录日志
		daoAccLog.addLog(accountId, sn, ip);
		// 扣减商币
		daoAcc.addCloudMoney(accountId, userid, BigDecimal.ZERO.subtract(cloudMoney));
		// 添加商币
		daoAcc.addCloudMoney(toAccountId, toUserid, cloudMoney);

		UserAccountInfo endAccInfo = getUserAccountInfo(userid);
		UserAccountInfo toEndAccInfo = getUserAccountInfo(toUserid);
		// 写资金日志明细
		// 先保存当前用户的赠送记录
		AccountNotice notice = new AccountNotice();
		notice.setAccountId(accountId);
		notice.setUserid(userid);
		notice.setToUserid(toUserid);
		notice.setCloudMoney(BigDecimal.ZERO.subtract(cloudMoney));
		notice.setTradeType(19); // 商币赠送
		notice.setSn(sn);// 流水号
		notice.setOuterTime(new Date());
		notice.setOperator(userid);// 操作人
		notice.setTitle(String.format("商币赠送给: %s ,商币:%s", toEndAccInfo.getName(), cloudMoney));
		notice.setMemo(memo);
		notice.setPaymentId(2);// 用户操作类型
		notice.setIp(ip);
		notice.setIsPaid((byte) 1);// 已付款
		notice.setMoneyType((short) 0);// 商币
		notice.setCreateTime(new Date());
		notice.setCloudMoneyDown(endAccInfo.getCloudMoney()); // 结存商币余额
		daoNotice.insert(notice);
		// 保存被赠送用户的记录
		notice = new AccountNotice();
		notice.setAccountId(toAccountId);
		notice.setUserid(toUserid);
		notice.setCloudMoney(cloudMoney);
		notice.setTradeType(19); // 商币赠送
		notice.setSn(PrimaryGenerater.getInstance().next());// 流水号
		notice.setOuterSn(sn);
		notice.setOuterTime(new Date());
		notice.setOperator(userid);// 操作人
		notice.setTitle(String.format("收到赠送的商币: %s ,赠送人:%s", cloudMoney, endAccInfo.getName()));
		notice.setMemo(memo);
		notice.setPaymentId(2);// 用户操作类型
		notice.setIp(ip);
		notice.setIsPaid((byte) 1);// 已付款
		notice.setMoneyType((short) 0);// 商币
		notice.setCreateTime(new Date());
		notice.setCloudMoneyDown(toEndAccInfo.getCloudMoney()); // 结存商币余额
		res=daoNotice.insert(notice);
		//释放锁
		AccountLock.unLock(accountId, userid);
		return res;
	}

	@Override
	public Integer buyCloudMoney(int accountId, int userid, int toAccountId, int toUserid, String sn, String ip,
			BigDecimal money, BigDecimal selfCloudMoney, BigDecimal otherCloudMoney) {
		Integer res = -1;
		if (!AccountLock.getLock(accountId, userid)) {
			return -11;
		}
		User uInfo = daoUser.getUser(userid);
		// 账户变动前记录日志
		daoAccLog.addLog(accountId, sn, ip);
		// 添加现金
		daoAcc.addMoney(accountId, userid, BigDecimal.ZERO.subtract(money));

		// 查询出账户结果
		UserAccountInfo endAccInfo = getUserAccountInfo(userid);
		if (endAccInfo.getMoney().compareTo(BigDecimal.ZERO) == -1) {
			log.error("CLOUD_ERROR:主动回滚[" + sn + "]res:-12");
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return -12;
		}
		// 写资金日志明细
		AccountNotice notice = new AccountNotice();
		notice.setAccountId(accountId);
		notice.setUserid(userid);
		notice.setMoney(BigDecimal.ZERO.subtract(money));
		notice.setTradeType(22); // 商币购买
		notice.setSn(sn);// 流水号
		notice.setOuterTime(new Date());
		notice.setOperator(userid);// 操作人
		notice.setTitle(String.format("用户购买商币,金额:%s,商币:%s", BigDecimal.ZERO.subtract(money), selfCloudMoney));
		notice.setMemo(null);
		notice.setPaymentId(4);// 用户操作类型
		notice.setIp(ip);
		notice.setIsPaid((byte) 1);// 已付款
		notice.setMoneyType((short) 1);// 现金
		notice.setCreateTime(new Date());
		notice.setMoneyDown(endAccInfo.getMoney());// 结存金额余额
		notice.setCloudMoneyDown(endAccInfo.getCloudMoney());// 结存商币

		// 添加商币
		daoAcc.addCloudMoney(accountId, userid, selfCloudMoney);
		daoNotice.insert(notice);
		notice = new AccountNotice();
		notice.setAccountId(accountId);
		notice.setUserid(userid);
		notice.setCloudMoney(selfCloudMoney);
		notice.setTradeType(22); // 商币购买22
		notice.setSn(PrimaryGenerater.getInstance().next());// 流水号
		// 来自哪个流水号 Csn
		notice.setCsn(sn);
		notice.setOuterTime(new Date());
		notice.setOperator(userid);// 操作人
		notice.setTitle(String.format("用户购买商币,金额:%s,商币:%s", BigDecimal.ZERO.subtract(money), selfCloudMoney));
		notice.setMemo(null);
		notice.setPaymentId(4);// 4余额
		notice.setIp(ip);
		notice.setIsPaid((byte) 1);// 已付款
		notice.setMoneyType((short) 0);// 商币
		notice.setCreateTime(new Date());
		notice.setMoneyDown(endAccInfo.getMoney());
		notice.setCloudMoneyDown(endAccInfo.getCloudMoney()); // 结存商币余额
		daoNotice.insert(notice);

		// 接收方 会员-----加商币
		daoAcc.addCloudMoney(toAccountId, toUserid, otherCloudMoney);
		UserAccountInfo toAccInfo = getUserAccountInfo(toUserid);
		notice = new AccountNotice();
		notice.setAccountId(toAccountId);
		notice.setUserid(toUserid);
		notice.setCloudMoney(otherCloudMoney);
		notice.setTradeType(22); // 商币购买
		notice.setSn(PrimaryGenerater.getInstance().next());// 流水号
		notice.setCsn(sn);// 流水号
		notice.setOuterTime(new Date());
		notice.setOperator(toUserid);// 操作人
		notice.setFromUserId(userid);
		notice.setTitle(String.format("%s购买商币:%s", uInfo.getName(), otherCloudMoney));
		notice.setMemo(null);
		notice.setPaymentId(4);// 用户操作类型
		notice.setIp(ip);
		notice.setIsPaid((byte) 1);// 已付款
		notice.setMoneyType((short) 0);// 商币
		notice.setCreateTime(new Date());
		notice.setMoneyDown(toAccInfo.getMoney());// 结存金额余额
		notice.setCloudMoneyDown(toAccInfo.getCloudMoney());// 结存商币
		res = daoNotice.insert(notice);

		// 给接收方的 推荐人返币 比例是 3% 为消费行为
		BigDecimal fee = new BigDecimal("0.03");
		recommendSer.buyCloudMoney(otherCloudMoney, fee, toUserid, sn, new Integer("22"));

		// 给商家 推荐人返币 比例是2% 商家收款行为
		fee = new BigDecimal("0.02");
		// 商家的推荐人的返币总额公式
		// 总额=( selfCloudMoney 乘以 100 在除以15 ) ，比例是 2%
		BigDecimal merchantRecommendCloudMoney = selfCloudMoney.multiply(new BigDecimal("100"))
				.divide(new BigDecimal("15"), 2, BigDecimal.ROUND_HALF_UP);
		recommendSer.buyCloudMoney(merchantRecommendCloudMoney, fee, userid, sn, new Integer("22"));
		//释放锁
		AccountLock.unLock(accountId, userid);
		return res;
	}

	@Override
	public Integer changeCloudMoneyToShare(int accountId, int userid, String sn, String ip, BigDecimal cloudMoney,
			BigDecimal cloudShares) {
		Integer res = -1;
		if (!AccountLock.getLock(accountId, userid)) {
			return -11;
		}
		// 账户变动前记录日志
		daoAccLog.addLog(accountId, sn, ip);
		// 扣减银元
		daoAcc.addCloudMoney(accountId, userid, BigDecimal.ZERO.subtract(cloudMoney));
		// 添加股权
		daoAcc.addCloudShares(accountId, userid, cloudShares);

		// 查询出账户结果
		UserAccountInfo endAccInfo = getUserAccountInfo(userid);
		if (endAccInfo.getMoney().compareTo(BigDecimal.ZERO) == -1) {
			log.error("CLOUD_ERROR:主动回滚[" + sn + "]res:-12");
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return -12;
		}
		// 写资金日志明细
		AccountNotice notice = new AccountNotice();
		notice.setAccountId(accountId);
		notice.setUserid(userid);
		notice.setCloudMoney(BigDecimal.ZERO.subtract(cloudMoney));
		notice.setTradeType(29); // 兑换期权
		notice.setSn(sn);// 流水号
		notice.setOuterTime(new Date());
		notice.setOperator(userid);// 操作人
		notice.setTitle(String.format("购买期权,商币:%s", BigDecimal.ZERO.subtract(cloudMoney)));
		notice.setMemo(null);
		notice.setPaymentId(4);// 用户操作类型
		notice.setIp(ip);
		notice.setIsPaid((byte) 1);// 已付款
		notice.setMoneyType((short) 0);// 银元
		notice.setCreateTime(new Date());
		notice.setMoneyDown(endAccInfo.getMoney());// 结存金额余额
		notice.setCloudMoneyDown(endAccInfo.getCloudMoney());// 结存银元
		notice.setCloudSharesDown(endAccInfo.getCloudShares());// 结存期权
		daoNotice.insert(notice);
		notice = new AccountNotice();
		notice.setAccountId(accountId);
		notice.setUserid(userid);
		notice.setCloudShares(cloudShares);
		notice.setTradeType(29); // 兑换期权
		notice.setSn(PrimaryGenerater.getInstance().next());// 流水号
		notice.setOuterSn(sn);
		notice.setOuterTime(new Date());
		notice.setOperator(userid);// 操作人
		notice.setTitle(String.format("购买期权,期权:+%s", cloudShares));
		notice.setMemo(null);
		notice.setPaymentId(4);// 用户操作类型
		notice.setIp(ip);
		notice.setIsPaid((byte) 1);// 已付款
		notice.setMoneyType((short) 2);// 期权
		notice.setCreateTime(new Date());
		notice.setMoneyDown(endAccInfo.getMoney());// 结存金额余额
		notice.setCloudMoneyDown(endAccInfo.getCloudMoney());// 结存银元
		notice.setCloudSharesDown(endAccInfo.getCloudShares());// 结存期权
		res = daoNotice.insert(notice);
		//释放锁
		AccountLock.unLock(accountId, userid);
		return res;
	}

}
